package GUI;

import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.Font;
import javax.swing.SwingConstants;
import javax.swing.border.EtchedBorder;
import javax.swing.JSeparator;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.LineBorder;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.UIManager;

import Algorithms.AlgorithmManager;
import cytoscape.CyNetwork;
import cytoscape.Cytoscape;
import cytoscape.task.ui.JTaskConfig;
import cytoscape.task.util.TaskManager;
import cytoscape.view.CyNetworkView;
import cytoscape.view.cytopanels.CytoPanelImp;

import java.awt.SystemColor;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.awt.Dimension;
import javax.swing.JTextPane;
import javax.swing.JList;

public class MainUserPanel extends JPanel {
	
	// singleton:
	private static MainUserPanel instance = null;
	
	public static MainUserPanel getMainUserPanel()
	{
		if (instance==null)
			instance = new MainUserPanel();
		return instance;
	}
	
	public void destroy()
	{
		instance=null;
	}
	
	AboutWindow about;
	private boolean numClustersOpen, parametersOpen, selectionOpen;
	
	private MainUserPanel() {
		
		setPreferredSize(new Dimension(248, 610));
		setAutoscrolls(true);
		setMinimumSize(new Dimension(235, 10));
		setLayout(null);
		selectionOpen=parametersOpen=numClustersOpen=true;
		JLabel lblExtendedFuzzyClustering = new JLabel("Extended Fuzzy Clustering");
		lblExtendedFuzzyClustering.setHorizontalAlignment(SwingConstants.CENTER);
		lblExtendedFuzzyClustering.setFont(new Font("Verdana", Font.BOLD, 14));
		lblExtendedFuzzyClustering.setBounds(10, 45, 217, 18);
		add(lblExtendedFuzzyClustering);
		
		numClustersOutsidePanel = new JPanel();
		numClustersOutsidePanel.setBorder(new CompoundBorder(new LineBorder(new Color(171, 173, 179)), new CompoundBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), new LineBorder(new Color(171, 173, 179)))));
		numClustersOutsidePanel.setBounds(10, 74, 217, 128);
		add(numClustersOutsidePanel);
		numClustersOutsidePanel.setLayout(null);
		
		numClustersToggle = new JLabel("-");
		numClustersToggle.setFont(new Font("Verdana", Font.PLAIN, 12));
		numClustersToggle.setHorizontalTextPosition(SwingConstants.CENTER);
		numClustersToggle.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if (numClustersOpen)
				{
					numClustersInsidePanel.setVisible(false);
					numClustersOutsidePanel.setSize(numClustersOutsidePanel.getWidth(),40);
					numClustersToggle.setText("+");
				}
				else
				{
					numClustersInsidePanel.setVisible(true);
					numClustersOutsidePanel.setSize(numClustersOutsidePanel.getWidth(),45+11+numClustersInsidePanel.getHeight());
					numClustersToggle.setText("-");
				}
				numClustersOpen=!numClustersOpen;
				relocatePanels();
			}
		});
		numClustersToggle.setBounds(10, 11, 18, 18);
		numClustersOutsidePanel.add(numClustersToggle);
		numClustersToggle.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		numClustersToggle.setHorizontalAlignment(SwingConstants.CENTER);
		
		JLabel lblNewLabel = new JLabel("Number of Clusters");
		lblNewLabel.setBounds(38, 11, 136, 18);
		numClustersOutsidePanel.add(lblNewLabel);
		
		numClustersInsidePanel = new JPanel();
		numClustersInsidePanel.setBounds(10, 45, 197, 68);
		numClustersOutsidePanel.add(numClustersInsidePanel);
		numClustersInsidePanel.setLayout(null);
		
		numClustersRadio1 = new JRadioButton("Predefined: ");
		numClustersRadio1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				numClustersRadio2.setSelected(false);
				numClustersInput.setEnabled(true);
			}
		});
		numClustersRadio1.setBounds(6, 7, 108, 23);
		numClustersInsidePanel.add(numClustersRadio1);
		
		numClustersInput = new JTextField();
		numClustersInput.setEnabled(false);
		numClustersInput.setFont(new Font("Verdana", Font.BOLD, 12));
		numClustersInput.setBounds(120, 8, 67, 20);
		numClustersInsidePanel.add(numClustersInput);
		numClustersInput.setColumns(10);
		
		numClustersRadio2 = new JRadioButton("Undefined");
		numClustersRadio2.setSelected(true);
		numClustersRadio2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				numClustersRadio1.setSelected(false);
				numClustersInput.setEnabled(false);
			}
		});
		numClustersRadio2.setBounds(6, 35, 109, 23);
		numClustersInsidePanel.add(numClustersRadio2);
		
		parametersOutsidePanel = new JPanel();
		parametersOutsidePanel.setLayout(null);
		parametersOutsidePanel.setBorder(new CompoundBorder(new LineBorder(new Color(171, 173, 179)), new CompoundBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), new LineBorder(new Color(171, 173, 179)))));
		parametersOutsidePanel.setBounds(10, 213, 217, 175);
		add(parametersOutsidePanel);
		
		parametersToggle = new JLabel("-");
		parametersToggle.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if (parametersOpen)
				{
					parametersInsidePanel.setVisible(false);
					parametersOutsidePanel.setSize(numClustersOutsidePanel.getWidth(),40);
					parametersToggle.setText("+");
				}
				else
				{
					parametersInsidePanel.setVisible(true);
					parametersOutsidePanel.setSize(parametersOutsidePanel.getWidth(),45+11+parametersInsidePanel.getHeight());
					parametersToggle.setText("-");
				}
				parametersOpen=!parametersOpen;
				relocatePanels();
			}
		});
		parametersToggle.setHorizontalTextPosition(SwingConstants.CENTER);
		parametersToggle.setHorizontalAlignment(SwingConstants.CENTER);
		parametersToggle.setFont(new Font("Verdana", Font.PLAIN, 12));
		parametersToggle.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		parametersToggle.setBounds(10, 11, 18, 18);
		parametersOutsidePanel.add(parametersToggle);
		
		lblClusteringParameters = new JLabel("Clustering Parameters");
		lblClusteringParameters.setBounds(38, 12, 136, 18);
		parametersOutsidePanel.add(lblClusteringParameters);
		
		parametersInsidePanel = new JPanel();
		parametersInsidePanel.setLayout(null);
		parametersInsidePanel.setBounds(10, 45, 197, 116);
		parametersOutsidePanel.add(parametersInsidePanel);
		
		parametersInput1 = new JTextField();
		
		
		parametersInput1.setFont(new Font("Verdana", Font.BOLD, 12));
		parametersInput1.setText("2.0");
		parametersInput1.setColumns(10);
		parametersInput1.setBounds(20, 31, 67, 20);
		parametersInsidePanel.add(parametersInput1);
		
		lblNewLabel_1 = new JLabel("Fuzzifier Parameter:");
		lblNewLabel_1.setBounds(10, 11, 122, 14);
		parametersInsidePanel.add(lblNewLabel_1);
		
		lblSensitivityThreshold = new JLabel("Sensitivity Threshold:");
		lblSensitivityThreshold.setBounds(10, 62, 156, 14);
		parametersInsidePanel.add(lblSensitivityThreshold);
		
		parametersInput2 = new JTextField();
		parametersInput2.setFont(new Font("Verdana", Font.BOLD, 12));
		parametersInput2.setText("0.05");
		parametersInput2.setColumns(10);
		parametersInput2.setBounds(20, 81, 67, 20);
		parametersInsidePanel.add(parametersInput2);
		
		selectionOutsidePanel = new JPanel();
		selectionOutsidePanel.setLayout(null);
		selectionOutsidePanel.setBorder(new CompoundBorder(new LineBorder(new Color(171, 173, 179)), new CompoundBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), new LineBorder(new Color(171, 173, 179)))));
		selectionOutsidePanel.setBounds(10, 399, 217, 128);
		add(selectionOutsidePanel);
		
		selectionToggle = new JLabel("-");
		selectionToggle.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				
				if (selectionOpen)
				{
					selectionInsidePanel.setVisible(false);
					selectionOutsidePanel.setSize(selectionOutsidePanel.getWidth(),40);
					selectionToggle.setText("+");
				}
				else
				{
					selectionInsidePanel.setVisible(true);
					selectionOutsidePanel.setSize(selectionOutsidePanel.getWidth(),45+11+selectionInsidePanel.getHeight());
					selectionToggle.setText("-");
				}
				selectionOpen=!selectionOpen;
				relocatePanels();
				
			}
		});
		selectionToggle.setHorizontalTextPosition(SwingConstants.CENTER);
		selectionToggle.setHorizontalAlignment(SwingConstants.CENTER);
		selectionToggle.setFont(new Font("Verdana", Font.PLAIN, 12));
		selectionToggle.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		selectionToggle.setBounds(10, 11, 18, 18);
		selectionOutsidePanel.add(selectionToggle);
		
		lblDataSelection = new JLabel("Data Selection");
		lblDataSelection.setBounds(38, 11, 136, 18);
		selectionOutsidePanel.add(lblDataSelection);
		
		selectionInsidePanel = new JPanel();
		selectionInsidePanel.setLayout(null);
		selectionInsidePanel.setBounds(10, 45, 197, 68);
		selectionOutsidePanel.add(selectionInsidePanel);
		
		selectionRadio1 = new JRadioButton("Cluster entire network");
		selectionRadio1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectionRadio2.setSelected(false);
			}
		});
		selectionRadio1.setSelected(true);
		selectionRadio1.setBounds(6, 7, 185, 23);
		selectionInsidePanel.add(selectionRadio1);
		
		selectionRadio2 = new JRadioButton("Cluster selection only");
		selectionRadio2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectionRadio1.setSelected(false);
			}
		});
		selectionRadio2.setBounds(6, 35, 185, 23);
		selectionInsidePanel.add(selectionRadio2);
		
		btnRun = new JButton("Run Algorithm");
		btnRun.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				runPressed();
			}
		});
		btnRun.setBounds(62, 547, 114, 23);
		add(btnRun);
		
		warning = new JTextArea();
		warning.setVisible(false);
		warning.setOpaque(false);
		warning.setBackground(SystemColor.scrollbar);
		warning.setFocusable(false);
		warning.setFocusTraversalKeysEnabled(false);
		warning.setEditable(false);
		warning.setWrapStyleWord(true);
		warning.setFont(new Font("Verdana", Font.PLAIN, 11));
		warning.setLineWrap(true);
		warning.setRows(2);
		warning.setText("One or more parameters are incorrect or missing.");
		warning.setBounds(10, 581, 217, 52);
		add(warning);
		
		btnExit = new JLabel("");
		btnExit.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
					exitClicked();
			}
		});
		btnExit.setToolTipText("Close Extended Fuzzy Clustering control panel");
		btnExit.setBounds(195, 11, 30, 30);
		add(btnExit);
		
		btnHelp = new JLabel("");
		btnHelp.setToolTipText("Help");
		btnHelp.setBounds(50, 11, 30, 30);
		add(btnHelp);
		
		btnAbout = new JLabel("");
		btnAbout.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				about= new AboutWindow();
				about.setVisible(true);
			}
		});
		btnAbout.setToolTipText("About Extended Fuzzy Clustering plugin");
		btnAbout.setBounds(10, 11, 30, 30);
		add(btnAbout);
		
		
		ImageIcon iconExit = new ImageIcon(getClass().getResource("/btnExit.png"));
		ImageIcon iconHelp = new ImageIcon(getClass().getResource("/btnHelp.png"));
		ImageIcon iconAbout = new ImageIcon(getClass().getResource("/btnAbout.png"));
		btnExit.setIcon(iconExit);
		btnHelp.setIcon(iconHelp);
		btnAbout.setIcon(iconAbout);
		relocatePanels();
	}

	private static final long serialVersionUID = 1L;
	private JLabel numClustersToggle;
	private JPanel numClustersInsidePanel;
	private JPanel numClustersOutsidePanel;
	private JTextField numClustersInput;
	private JRadioButton numClustersRadio1;
	private JRadioButton numClustersRadio2;
	private JPanel parametersOutsidePanel;
	private JLabel parametersToggle;
	private JLabel lblClusteringParameters;
	private JPanel parametersInsidePanel;
	private JTextField parametersInput1;
	private JLabel lblNewLabel_1;
	private JLabel lblSensitivityThreshold;
	private JTextField parametersInput2;
	private JPanel selectionOutsidePanel;
	private JLabel selectionToggle;
	private JLabel lblDataSelection;
	private JPanel selectionInsidePanel;
	private JRadioButton selectionRadio1;
	private JRadioButton selectionRadio2;
	private JButton btnRun;
	private JTextArea warning;
	private JLabel btnExit;
	private JLabel btnHelp;
	private JLabel btnAbout;
	
	
	private void relocatePanels()
	{
		parametersOutsidePanel.setLocation(10, numClustersOutsidePanel.getY()+numClustersOutsidePanel.getHeight()+11);
		selectionOutsidePanel.setLocation(10, parametersOutsidePanel.getY()+parametersOutsidePanel.getHeight()+11);
		btnRun.setLocation(btnRun.getX(), selectionOutsidePanel.getY()+selectionOutsidePanel.getHeight()+20);
		warning.setLocation(10, btnRun.getHeight() + btnRun.getY()+11);
	}
	
	private void exitClicked()
	{
		CytoPanelImp ctrlPanel = (CytoPanelImp) Cytoscape.getDesktop().getCytoPanel(SwingConstants.WEST);
		ctrlPanel.remove(this);
		
		this.destroy();
	}
	
	private void runPressed()
	{
		boolean extended=numClustersRadio2.isSelected();

		int numClusters=0;
		if (!extended)
		{
			try{
				numClusters=Integer.parseInt(numClustersInput.getText());
			
			}
			catch(Exception e)
			{
				JOptionPane.showMessageDialog(this,  "ERROR: invalid number of clusters, terminating...\n"   );
				return;
			}
		}
		else
		{
			
		}
		
		
		double m;
		try{
			m=Double.parseDouble(parametersInput1.getText());
		}
		catch(Exception e)
		{
			JOptionPane.showMessageDialog(this,  "ERROR: invalid fuzzifier parameter, terminating...\n"   );
			return;
		}
		
		double eps;
		try{
			eps=Double.parseDouble(parametersInput2.getText());
			//JOptionPane.showMessageDialog(this,  "epsillon = " + parametersInput2.getText()  );
		}
		catch(Exception e)
		{
			JOptionPane.showMessageDialog(this,  "ERROR: invalid epsillon, terminating...\n"   );
			return;
		}
		
		CyNetwork graph=Cytoscape.getCurrentNetwork();
		CyNetworkView view = Cytoscape.getCurrentNetworkView();
		if (graph==null || graph.getNodeCount()==0)
		{
			JOptionPane.showMessageDialog(this, "Empty network or no network selected, terminating...\n"   );
			return;			
		}
		
		
		//JOptionPane.showMessageDialog(this, "all OK, network contains "+graph.getNodeCount() + " nodes."  );
		// if got to this point, all is ok, start algorithm:
		AlgorithmManager algorithm = new AlgorithmManager(extended, numClusters, m, eps, graph,view, selectionRadio2.isSelected());
		
		JTaskConfig taskConfig = new JTaskConfig();
		taskConfig.setModal(false);
		
		TaskManager.executeTask(algorithm, taskConfig);
	}
}
